<script setup lang="ts">
import SpineWebGl42 from '@/component/spine/Spine42.vue'
import { onMounted, onUnmounted, ref, watch } from 'vue'
import {
  spineData,
  assetsPath,
  offset,
  background,
  selectWallpaperValueKey,
  bgmToggleKey,
  bgmToggle,
} from '@/assets/global.ts'
import { selectALLOptions } from '@/assets/setting.ts'

const size = ref({
  width: 1920,
  height: 1080,
})
const pos = ref({
  top: 0,
  left: 0,
})

function getCanvasSize() {
  const windowWidth = window.innerWidth
  const windowHeight = window.innerHeight

  if (windowWidth / windowHeight >= 16 / 9) {
    // 宽度更大的时候
    size.value.width = windowWidth
    size.value.height = windowWidth / 16 * 9
  } else {
    // 高度更大的时候
    size.value.height = windowHeight
    size.value.width = windowHeight * 16 / 9
  }
  // 处理偏移量
  const realWidth = 100 / windowWidth * size.value.width
  const offsetX = offset.value.left / 100 * realWidth - 50
  const maxLeft = realWidth - 100
  const minLeft = 0
  if (offsetX <= maxLeft && offsetX >= minLeft) {
    pos.value.left = offsetX
  } else {
    if (Math.abs(offsetX - minLeft) < Math.abs(offsetX - maxLeft)) {
      pos.value.left = minLeft
    } else {
      pos.value.left = maxLeft
    }
  }
  const realHeight = 100 / windowHeight * size.value.height
  const offsetY = offset.value.top / 100 * realHeight - 50
  const maxTop = realHeight - 100
  const minTop = 0
  if (offsetY <= maxTop && offsetY >= minTop) {
    pos.value.top = offsetY
  } else {
    if (Math.abs(offsetY - minTop) < Math.abs(offsetY - maxTop)) {
      pos.value.top = minTop
    } else {
      pos.value.top = maxTop
    }
  }
}

onMounted(() => {
  if (localStorage.getItem(selectWallpaperValueKey)) {
    const index = Number(localStorage.getItem(selectWallpaperValueKey))
    if (!isNaN(index) && selectALLOptions[index]) {
      selectALLOptions[index].callback()
    }
  }
  if (localStorage.getItem(bgmToggleKey)) {
    bgmToggle.value = localStorage.getItem(bgmToggleKey) === 'true'
  }
  getCanvasSize()
  window.addEventListener('resize', getCanvasSize)
})

onUnmounted(() => {
  window.removeEventListener('resize', getCanvasSize)
})

watch(() => offset.value, () => {
  getCanvasSize()
})

watch(() => spineData.value, () => {
  getCanvasSize()
})
</script>

<template>
  <div class="wallpaper-wrapper">
    <Transition name="fade">
      <div class="wallpaper-bg" v-if="background" :style="{
        background: `url('${background}')`,
        width: size.width + 'px',
        height: size.height + 'px',
        top: - pos.top + '%',
        left: - pos.left + '%',
      }"></div>
    </Transition>
    <Transition name="fade">
      <SpineWebGl42
        id="wallpaper"
        v-show="spineData && spineData.length"
        :spine-data="spineData"
        :default-width="1920"
        :default-height="1080"
        :size="size"
        :assets-path="assetsPath"
        :style="{
          width: size.width + 'px',
          height: size.height + 'px',
          top: - pos.top + '%',
          left: - pos.left + '%',
        }"
      ></SpineWebGl42>
    </Transition>
  </div>
</template>

<style scoped>
.wallpaper-wrapper {
  width: 100vw; /* 视口宽度 */
  height: 100vh; /* 视口高度 */
  background-color: rgb(13, 13, 13);
  position: absolute;
  overflow: hidden;

  #wallpaper {
    position: relative;
  }

  .wallpaper-bg {
    position: absolute;
    background-size: cover !important;
    width: 100vw;
    height: 100vh;
  }
}

.fade-enter-active, .fade-leave-active,
.fade-enter-active, .fade-leave-active {
  transition: opacity 0.5s ease-in-out;
}

.fade-enter-from, .fade-leave-to,
.fade-enter-from, .fade-leave-to { /* .fade-leave-active 在进入时生效 */
  opacity: 0;
}

.fade-enter-to, .fade-leave,
.fade-enter-to, .fade-leave { /* .fade-leave-active 在离开时生效 */
  opacity: 1;
}
</style>